package edu.uts.reekie.designer.implementation.actions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.RotatableDecoration;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWorkbenchPart;

import edu.uts.reekie.designer.Messages;
import edu.uts.reekie.designer.ReekieDesignerPlugin;
import edu.uts.reekie.designer.implementation.edit.ConnectorEditPart;
import edu.uts.reekie.designer.implementation.edit.ViewComponentEditPart;
import edu.uts.reekie.designer.implementation.model.Connector;
import edu.uts.reekie.designer.implementation.model.ViewComponent;
import edu.uts.reekie.designer.implementation.model.Connector.Style;
import edu.uts.reekie.designer.implementation.model.commands.SetConnectorStyleCommand;

public class SetConnectorStyleAction 
	extends org.eclipse.gef.ui.actions.SelectionAction
	{
		
	public interface Factory {
		SetConnectorStyleCommand createCommand();
		SetConnectorStyleAction createAction(IWorkbenchPart part);
	}

	private static Map<String, Factory> all;
	static {
		all = new HashMap<String,Factory>();
		all.put(getId(Style.Normal), new Factory(){

			@Override
			public SetConnectorStyleCommand createCommand() {
				// TODO Auto-generated method stub
				return new SetConnectorStyleCommand(Style.Normal);
			}
			@Override
			public SetConnectorStyleAction createAction(IWorkbenchPart part) {
				// TODO Auto-generated method stub
				return new SetConnectorStyleAction(part, Style.Normal);
			}
		
		});
		all.put(getId(Style.ApiCall), new Factory(){

			@Override
			public SetConnectorStyleCommand createCommand() {
				// TODO Auto-generated method stub
				return new SetConnectorStyleCommand(Style.ApiCall);
			}
			@Override
			public SetConnectorStyleAction createAction(IWorkbenchPart part) {
				// TODO Auto-generated method stub
				return new SetConnectorStyleAction(part, Style.ApiCall);
			}
		
		});
		all.put(getId(Style.Callback), new Factory(){

			@Override
			public SetConnectorStyleCommand createCommand() {
				// TODO Auto-generated method stub
				return new SetConnectorStyleCommand(Style.Callback);
			}
			
			@Override
			public SetConnectorStyleAction createAction(IWorkbenchPart part) {
				// TODO Auto-generated method stub
				return new SetConnectorStyleAction(part, Style.Callback);
			}
		});
		all.put(getId(Style.Signal), new Factory(){

			@Override
			public SetConnectorStyleCommand createCommand() {
				// TODO Auto-generated method stub
				return new SetConnectorStyleCommand(Style.Signal);
			}
			
			@Override
			public SetConnectorStyleAction createAction(IWorkbenchPart part) {
				// TODO Auto-generated method stub
				return new SetConnectorStyleAction(part, Style.Signal);
			}
		
		});
		all.put(getId(Style.NetworkProtocol), new Factory(){

			@Override
			public SetConnectorStyleCommand createCommand() {
				// TODO Auto-generated method stub
				return new SetConnectorStyleCommand(Style.NetworkProtocol);
			}
			@Override
			public SetConnectorStyleAction createAction(IWorkbenchPart part) {
				// TODO Auto-generated method stub
				return new SetConnectorStyleAction(part, Style.NetworkProtocol);
			}
		
		});
		
			
		
	}
	
	public static Map<String,Factory> all() {
		return all;
	}
	public static String[] getAllIds() {
		String[] a = new String[all.keySet().size()];
		all.keySet().toArray(a);
		return a;
	}
	
	public static String getId(Style s){
		String suffix = " to ";
		String dec = "";
		switch (s)
		{
		case Normal:
			
			dec = "Normal";
			break;
		case ApiCall:
			dec = "API Call";
			break;
			
		case Callback:
			dec = "callback";
			break;
			
		case Signal:
			dec = "Signal";
			break;
		case NetworkProtocol:
			dec = "Network Protocol";
			break;
		}
		
		
		return "Change to " + dec;
		
	}


	Request request;
	
	private Style style;
	private static int count = 0;
	private int c;

	public SetConnectorStyleAction(IWorkbenchPart part, Style s) {
		super(part);
		
		this.style = s;
		this.c = count++;
		String id = getId(s);
		
		request = new Request(id);
		setText(id);
		setToolTipText(id);
		setId(id);
		
		// TODO: change to real icon
		setImageDescriptor(
				ImageDescriptor.createFromFile(ReekieDesignerPlugin.class,"icons/plus.gif")); //$NON-NLS-1$
			
		
		setHoverImageDescriptor(getImageDescriptor());
	}

	protected boolean calculateEnabled() {
		return canPerformAction();
	}

	private boolean canPerformAction() {
		
		if (getSelectedObjects().isEmpty())
			return false;
		
		
		List<?> parts = getSelectedObjects();
		for (int i=0; i<parts.size(); i++){
			Object o = parts.get(i);
			if (!(o instanceof ConnectorEditPart))
				return false;
			
			ConnectorEditPart part = (ConnectorEditPart)o;
			if (!(part.getModel() instanceof Connector))
				return false;
			
			Connector model = (Connector)part.getModel();
			
			if (model.getStyle()==style){
				return false;
			}
						
		}
		return true;
	}

	private Command getCommand() {
		
		List editparts = getSelectedObjects();
		CompoundCommand cc = new CompoundCommand();
		cc.setDebugLabel(getId());//$NON-NLS-1$
		for (int i=0; i < editparts.size(); i++) {
			EditPart part = (EditPart)editparts.get(i);
			cc.add(part.getCommand(request));
		}
		return cc;
	}

	public void run() {
		execute(getCommand());
	}
}
